#ifndef _SM3_H_
#define _SM3_H_

#include "typedef.h"

#define SM3_DATA_LEN	32

#define SM3_IV_A 0x7380166f
#define SM3_IV_B 0x4914b2b9
#define SM3_IV_C 0x172442d7
#define SM3_IV_D 0xda8a0600
#define SM3_IV_E 0xa96f30bc
#define SM3_IV_F 0x163138aa
#define SM3_IV_G 0xe38dee4d
#define SM3_IV_H 0xb0fb0e4e

#define SM3_T_0 0x79CC4519
#define SM3_T_1 0x7A879D8A

typedef struct __attribute__((aligned(4))) {
	uint32 state[8]; /* Internal state of the SM3 hash algorithm (256 bits total, stored as 8 32-bit integers) */
    uint8_t buf[64]; /* Buffer to store data blocks to be processed */
    uint32 cur_buf_len; /* Current length of data in the buffer (in bytes) */
    uint64 compressed_len; /* Total length of data that has been compressed */
}sm3_ctx;


/************************************************************************************************************
 *  Cry_SM3_Init()
 ***********************************************************************************************************/
/*!
 * \brief         Initializes the SM3 context.
 * \details       This function initializes the SM3 context structure, setting the internal state to the 
 *                SM3 initial vector (IV) as defined by the SM3 standard. It also clears the message buffer
 *                and resets the buffer length and compressed data length.
 *
 * \param[in,out] ctx         Pointer to the SM3 context structure to be initialized.
 *
 * \return        E_OK        The initialization completed successfully.
 * \return        E_NOT_OK    The initialization failed (e.g., NULL pointer input).
 *
 * \pre           The calling environment must provide a valid `ctx` pointer.
 * \context       ANY
 * \reentrant     FALSE
 * \synchronous   TRUE
 * \config        -
 **********************************************************************************************************/
extern Std_ReturnType Cry_SM3_Init(sm3_ctx *ctx);


/************************************************************************************************************
 *  Cry_SM3_Update()
 ***********************************************************************************************************/
/*!
 * \brief         Updates the SM3 context with new input data.
 * \details       This function continuously appends input data to the internal buffer \a ctx->buf. Whenever
 *                the buffer size reaches 64 bytes, it immediately calls the SM3 compression function 
 *                (\c Cry_SM3_Process) to process the data. The total amount of compressed data is tracked 
 *                in bits by \a ctx->compressed_len.
 *
 * \param[in,out] ctx        Pointer to the SM3 context structure.
 *                           - On entry, \a ctx->cur_buf_len indicates how many bytes are currently stored 
 *                             in the buffer.
 *                           - On exit, \a ctx->cur_buf_len is updated to reflect any remaining unprocessed bytes.
 *
 * \param[in]     input      Pointer to the input data to be hashed.
 *
 * \param[in]     iLen       The length of the input data (in bytes).
 *
 * \return        E_OK       Operation completed successfully.
 * \return        E_NOT_OK   One or more parameters are invalid (e.g., NULL pointer or misaligned addresses).
 *
 * \pre           - \a ctx and \a input must be valid, non-NULL pointers.
 *                - \a ctx->buf and \a input must be properly 4-byte aligned.
 * \context       ANY
 * \reentrant     FALSE
 * \synchronous   TRUE
 * \config        -
 **********************************************************************************************************/
extern Std_ReturnType Cry_SM3_Update(sm3_ctx *ctx, const uint8 *input, uint32 iLen);


/************************************************************************************************************
 *  Cry_SM3_GetHash()
 ***********************************************************************************************************/
/*!
 * \brief         Finalizes the SM3 hash computation and retrieves the hash value.
 * \details       This function computes the final hash value by processing any remaining data in the buffer,
 *                appending padding, and incorporating the total message length. The final 256-bit hash is
 *                stored in the provided output buffer.
 *
 * \param[in,out] ctx        Pointer to the SM3 context structure.
 *                           - \a ctx->buf: Holds unprocessed data (if any) to be finalized.
 *                           - \a ctx->compressed_len: Tracks the total compressed data length in bits.
 *
 * \param[out]    output     Pointer to a buffer where the 32-byte (256-bit) hash result will be written.
 *
 * \return        E_OK       Operation completed successfully.
 * \return        E_NOT_OK   Invalid input parameters (e.g., NULL pointer or misaligned buffer).
 *
 * \pre           - \a ctx and \a output must be valid, non-NULL pointers.
 *                - \a ctx->buf and \a output must be properly 4-byte aligned.
 * \context       ANY
 * \reentrant     FALSE
 * \synchronous   TRUE
 * \config        -
 **********************************************************************************************************/
extern Std_ReturnType Cry_SM3_GetHash(sm3_ctx *ctx, uint8 *output);


/************************************************************************************************************
 *  Cry_SM3_MainFunction()
 ***********************************************************************************************************/
/*!
 * \brief         Performs the full SM3 hash computation on the input data.
 * \details       This function provides a simplified interface for computing the SM3 hash. It initializes 
 *                an SM3 context, updates it with the input data, and retrieves the final 256-bit hash value.
 *                It handles initialization, data processing, and finalization in a single call.
 *
 * \param[in]     input      Pointer to the input data to be hashed.
 *                           - This must be a valid, non-NULL pointer.
 *                           - Input data does not need to be aligned.
 *
 * \param[in]     iLen       The length of the input data (in bytes).
 *                           - This must be a positive integer and should not exceed the system's memory limits.
 *
 * \param[out]    output     Pointer to a buffer where the 32-byte (256-bit) hash result will be written.
 *                           - This must be a valid, non-NULL pointer, and the buffer must be at least 32 bytes.
 *
 * \return        Std_ReturnType
 *                - \c E_OK:     Operation completed successfully.
 *                - \c E_NOT_OK: One or more parameters are invalid (e.g., NULL pointer, zero length).
 *
 * \pre           - \a input and \a output must be valid, non-NULL pointers.
 *                - \a iLen must be greater than zero.
 * \context       ANY
 * \reentrant     FALSE
 * \synchronous   TRUE
 * \config        -
 **********************************************************************************************************/
extern Std_ReturnType Cry_SM3_MainFunction(const uint8 *input, uint32 iLen, uint8 *output);

#endif /* _SM3_H_ */